################################################################################
# Speech Parsing
################################################################################

class Utterance:
    def __init__(self, nbest):
        self.nbest = nbest
        
        # Whole utterance with tags removed
        self.phrase = ""
        self.new_word = ""
        self.new_word_raw = ""
        self.learned_word = ""

        self.process_input(self.nbest[0][1])

    def print_nbest(self):
        print "---------------------------------------------------"
        print "Best guess: " + self.phrase
        print "---------------------------------------------------"
        for n in self.nbest:
            n0 = str(n[0])
            while len(n0) < 12:
                n0 += " "
            print n0, n[1]

    # This is currently assuming that there are only two tags, SUBWORD and LEARNED
    def process_input(self, string):
        inp_list = self.process_tags(string)
        self.phrase = ""
        for item in inp_list:
            if type(item) == str:
                self.phrase += item + " "
            else:
                if item[0] == "SUBWORD":
                    self.new_word = self.parse_word(item[1])
                    self.new_word_raw = item[1]
                    self.phrase += self.new_word + " "
                elif item[0] == "LEARNED":
                    self.learned_word = item[1]
                    self.phrase += self.learned_word + " "
        self.phrase = self.phrase.strip()
        
    def process_tags(self, string):
        inp_list = string.split()
        needs_processing = True
        while needs_processing == True:
            inp_list, needs_processing = self.process_tag(inp_list)
        return inp_list

    # Takes a list of string pieces and turns the first part with a tag into a touple
    def process_tag(self, inp):
        inp_list = inp[:]
        start_index = None
        end_index = None
        tag_name = None
        extracted_tag = False

        # Get where tag begins and ends
        for i in range(len(inp_list)):
            if "<$" in inp_list[i]:
                start_index = i
                # Extract the name of the tag, e.g. SUBWORD from <$SUBWORD>
                tag_name = inp_list[i][2:-1]
            elif "</$" in inp_list[i]:
                end_index = i
        
        if start_index != None and end_index != None:
            # Save everything between the open and close tags
            tag_contents = inp_list[start_index+1:end_index]
            # Replace tag contents with (tag_name, contents)
            # inp_list now looks like [raw, raw, raw, (tag_name, contents), raw, raw]
            inp_list = inp_list[:start_index] + [(tag_name, " ".join(tag_contents))] + inp_list[end_index+1:]
            extracted_tag = True

        return inp_list, extracted_tag

    # Parses a string of subwords into a word
    def parse_word(self, subwords):
        subwords_list = subwords.split()
        results = []
        for subword in subwords_list:
            if "<" in subword:
                # Cut off < and everything after it
                subword = subword[:subword.index("<")]
            # Remove all "_"
            subword = subword.split("_")
            subword = "".join(subword)
            results.append(subword)
        result = "".join(results)
        return result            
